package com.hjk.common.utils.http;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;


@Configuration
public class RestConfig {

    // 长链接保持时间长度10秒
    @Value("${restTemplate.timeToLive}")
    private long timeToLive = 10;
    // 设置最大链接数
    @Value("${restTemplate.maxTotal}")
    private int maxTotal = 120;
    // 单路由的并发数
    @Value("${restTemplate.defaultMaxPerRoute}")
    private int defaultMaxPerRoute = 50 ;
    // 重试次数3次
    @Value("${restTemplate.retryCount}")
    private int retryCount = 3 ;

    //链接超时配置
    @Value("${restTemplate.connectTimeout}")
    private int connectTimeout = 10000 ;

    //连接读取超时配置
    @Value("${restTemplate.socketTimeout}")
    private int readTimeout = 10000 ;

    // 连接池不够用时候等待时间长度设置
    @Value("${restTemplate.connectionRequestTimeout}")
    private int connectionRequestTimeout = 10000 ;

    @Bean
    public RestTemplate httpClientRestTemplate() {
        // 长链接保持时间长度10秒
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(timeToLive, TimeUnit.SECONDS);
        // 设置最大链接数
        poolingHttpClientConnectionManager.setMaxTotal(maxTotal);
        // 单路由的并发数
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);

        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);

        // 重试次数3次，并开启
        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, true));
        HttpClient httpClient = httpClientBuilder.build();
        // 保持长链接配置，keep-alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());

        HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

        // 链接超时配置 5秒
        httpComponentsClientHttpRequestFactory.setConnectTimeout(connectTimeout);
        // 连接读取超时配置
        httpComponentsClientHttpRequestFactory.setReadTimeout(readTimeout);
        // 连接池不够用时候等待时间长度设置
        httpComponentsClientHttpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);

        // 缓冲请求数据，POST大量数据，可以设定为true 我们这边机器比较内存较大
        httpComponentsClientHttpRequestFactory.setBufferRequestBody(true);

        RestTemplate restTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory); // 使用HttpClient，支持GZIP
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 支持中文编码
        return restTemplate;
    }

}
